#ifndef CSUPBR_TEXTURE_H
#define CSUPBR_TEXTURE_H

#include "geometry.h"
#include <memory>
#include <iostream>
#include <exception>

namespace csupbr {
    
    /**
     * \brief Texture
     * \p data ptr release is NOT supported in Texutre!!!
     */
    struct Texture {
        /**
         * \param data release not support in Texture
         */
        Texture(int width, int height, int channel, uint8_t* data = nullptr)
            : width(width), height(height), channel(channel),
             _data(data) {
            if (channel <= 0) {
                std::cerr << "csupbr::Texture::channel >> invalid channel: "
                          << channel << "\n";
                abort();
            }
        }

        virtual Spectrum evaluate(const Vec2f &uv) const {
            int u = std::clamp(static_cast<int>((uv.u) * width), 0, width - 1);
            int v = std::clamp(static_cast<int>((uv.v) * height), 0, height - 1);
            if (channel == 1) {
                auto r = TO_RGB_INV * _data[u * channel + channel * width * v];
                return {r, r, r};
            } else {
                Spectrum ret{0.f};
                for (int i = 0; i < 3; i++) {
                    ret[i] = TO_RGB_INV * _data[u * channel + channel * width * v + i];
                }
                return ret;
            }
        }

        int width, height, channel;
        uint8_t* _data = nullptr;
    };

}

#endif // !CSUPBR_TEXTURE_H